home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-08-02 | 60.0 KB | 1,757 lines |
- ;;; gnus-uu.el --- extract and view or save (uu)encoded files from gnus
- ;;
- ;; Author: Lars Ingebrigtsen <larsi@ifi.uio.no>
- ;; Created: 2 Oct 1993
- ;; Version: gnus-uu.el v 1.3 1993/12/07
- ;; Keyword: gnus
- ;;
- ;; All gnus-uu commands start with `C-c C-v'.
- ;;
- ;; Typing `C-c C-v C-v' (gnus-uu-decode-and-view) in the summary
- ;; buffer will try to find all articles in the same series, uudecode
- ;; them and view the resulting file(s).
- ;;
- ;; gnus-uu guesses what articles are in the series according to the
- ;; following simple rule: The subject must be identical, except for
- ;; the last two numbers of the line.
- ;;
- ;; For example: If you choose a subject called "cat.gif (2/3)" gnus-uu
- ;; will find all the articles that matches "^cat.gif
- ;; ([0-9]+/[0-9]+).*$". Subjects that are nonstandard, like "cat.gif
- ;; (2/3) Part 6 of a series", will not be properly recognized by 'C-c
- ;; C-v', and you have to mark the articles manually with '#'.
- ;;
- ;; Typing `C-c C-v v' (gnus-uu-decode-and-save) will do the same as
- ;; `C-c C-v C-v', except that it will not display the resulting file, but
- ;; save it instead.
- ;;
- ;; Typing `C-c C-v s' (gnus-uu-shar-and-save) does the same as `C-c
- ;; C-v v', and `C-c C-v C-s' (gnus-uu-shar-and-view) does the same as
- ;; `C-c C-v C-v', except that they unshar files instead, i. e. run
- ;; them through /bin/sh. Most shar files can be viewed and/or saved
- ;; with the normal uudecode commands, which is much safer, as no
- ;; foreign code is run.
- ;;
- ;; `#' (gnus-uu-mark-article) marks an article for later
- ;; decoding/unsharing/saving/viewing. The files will be decoded in the
- ;; sequence they were marked. To decode the files after you've marked
- ;; the articles you are interested in, type the corresponding key
- ;; strokes as the normal decoding commands, but put a `M-' in the last
- ;; keystroke. For instance, to perform a standard uudecode and view,
- ;; you would type `C-c C-v C-v'. To perform a marked uudecode and
- ;; view, say `C-v C-v M-C-v'. All the other view and save commands are
- ;; handled the same way; marked uudecode and save is then `C-c C-v
- ;; M-v'.
- ;;
- ;; `M-#' (gnus-uu-unmark-article) will remove the mark from a
- ;; previosly marked article.
- ;;
- ;; `C-c C-v C-u' (gnus-uu-unmark-all-articles) will remove the mark from
- ;; all marked articles.
- ;;
- ;; `C-c C-v C-r' (gnus-uu-mark-by-regexp) will prompt for a regular
- ;; expression and mark (forward) all articles matching that regular
- ;; expression.
- ;;
- ;; There's an additional way to reach the decoding functions to make
- ;; future expansions easier: `C-c C-v C-x'
- ;; (gnus-uu-multi-decode-and-view) and the corresponding save, marked
- ;; view and marked save keystrokes, `C-c C-v x', `C-c C-v M-C-x' and
- ;; `C-c C-v M-x' respectively. You will be prompted for decoding
- ;; method, like uudecode, shar or plain save.
- ;;
- ;; `C-c C-b' (gnus-uu-decode-and-show-in-buffer) will decode the
- ;; current article and display the results in an emacs buffer. This
- ;; might be useful if there's jsut some text in the current article
- ;; that has been uuencoded by some perverse poster.
- ;;
- ;; `C-c C-o' (gnus-uu-decode-and-save-all-articles) looks at all
- ;; unread articles in the current newsgroup and tries to uudecode
- ;; everything it can find. The user will be prompted for a directory
- ;; where the resulting files (if any) will be stored.
- ;;
- ;; `C-c C-l' (gnus-uu-edit-begin-line) lets you edit the begin line
- ;; of the current buffer. Useful to change an incorrect suffix or an
- ;; incorrect begin line.
- ;;
- ;;
- ;; When using the view commands, `C-c C-v C-v' for instance, gnus-uu
- ;; will (normally, see below) try to view the file according to the
- ;; rules given in gnus-uu-default-view-rules and
- ;; gnus-uu-user-view-rules. If it recognises the file, it will display
- ;; it immediately. If the file is some sort of archive, gnus-uu will
- ;; attempt to unpack the archive and see if any of the files in the
- ;; archive can be viewed. For instance, if you have a gzipped tar file
- ;; "pics.tar.gz" containing the files "pic1.jpg" and "pic2.gif",
- ;; gnus-uu will uncompress and detar the main file, and then view the
- ;; two pictures. This unpacking process is recursive, so if the
- ;; archive contains archives of archives, it'll all be unpacked.
- ;;
- ;; If the view command doesn't recognise the file type, or can't view
- ;; it because you don't have the viewer, or can't view *any* of the
- ;; files in the archive, the user will be asked if she wishes to have
- ;; the file saved somewhere. Note that if the decoded file is an
- ;; archive, and gnus-uu manages to view some of the files in the
- ;; archive, it won't tell the user that there were some files that
- ;; were unviewable. See "Interactive view" for a different approach.
- ;;
- ;;
- ;; Note that gnus-uu adds a function to `gnus-exit-group-hook' to
- ;; clear the list of marked articles and check for any generated files
- ;; that might have escaped deletion if the user typed `C-g'.
- ;;
- ;;
- ;; `C-c C-v C-a' (gnus-uu-toggle-asynchronous) toggles the
- ;; gnus-uu-asynchronous variable. See below for explanation.
- ;;
- ;; `C-c C-v C-q' (gnus-uu-toggle-query) toggles the
- ;; gnus-uu-ask-before-view variable. See below for explanation.
- ;;
- ;; `C-c C-v C-p' (gnus-uu-toggle-always-ask) toggles the
- ;; gnus-uu-view-and-save variable. See below for explanation.
- ;;
- ;; `C-c C-v C-k' (gnus-uu-toggle-kill-carriage-return) toggles the
- ;; gnus-uu-kill-carriage-return variable. See below for explanation.
- ;;
- ;; `C-c C-v C-i' (gnus-uu-toggle-interactive-view) toggles interactive
- ;; mode. If it is turned on, gnus-uu won't view files immediately but
- ;; give you a buffer with the default commands and files and lets you
- ;; edit the commands and execute them at leisure.
- ;;
- ;; `C-c C-v C-t' (gnus-uu-toggle-any-variable) is an interface to the
- ;; five toggle commands listed above.
- ;;
- ;;
- ;; Customization
- ;;
- ;; To load this file when starting gnus, put sumething like the
- ;; following in your .emacs file:
- ;;
- ;; (setq gnus-group-mode-hook
- ;; '(lambda () (load "gnus-uu")))
- ;;
- ;; To make gnus-uu use, for instance, "xli" to view JPEGs and GIFs,
- ;; put this in your .emacs file:
- ;;
- ;; (setq gnus-uu-user-view-rules
- ;; (list
- ;; '("jpg$\\|gif$" "xli")
- ;; ))
- ;;
- ;; This variable is a list where each list item is a list containing
- ;; two strings. The first string is a regular expression. If the file
- ;; name is matched by this expression, the command given in the
- ;; second string is executed on this file. If the command contains
- ;; "%s", the file will be inserted there in the command string. Eg.
- ;; "giftoppm %s | xv -" will result in the file name being inserted at
- ;; the "%s".
- ;;
- ;; If you don't want to display certain file types, like if you
- ;; haven't got sound capabilities, you could put something like
- ;;
- ;; (setq gnus-uu-user-view-rules
- ;; (list
- ;; '("au$\\|voc$\\|wav$" nil)
- ;; ))
- ;;
- ;; in your .emacs file.
- ;;
- ;; There's a similar variable called 'gnus-uu-user-archive-rules'
- ;; which gives a list of unarcers to use when looking inside archives
- ;; for files to display.
- ;;
- ;; If you don't want gnus-uu to look inside archives for files to
- ;; display, say
- ;;
- ;; (setq gnus-uu-do-not-unpack-archives t)
- ;;
- ;;
- ;; If you want gnus-uu to ask you if you want to save a file after
- ;; viewing, say
- ;;
- ;; (setq gnus-uu-view-and-save t)
- ;;
- ;;
- ;; If you don't want to wait for the viewing command to finish before
- ;; returning to emacs, say
- ;;
- ;; (setq gnus-uu-asynchronous t)
- ;;
- ;;
- ;; This can be useful if you're viewing long .mod files, for instance,
- ;; which often takes several minutes. Note, however, that since
- ;; gnus-uu doesn't ask, and if you are viewing an archive with lots of
- ;; viewable files, you'll get them all up more or less at once, which
- ;; can be confusing, to say the least. To get gnus-uu to ask you
- ;; before viewing a file, say
- ;;
- ;; (setq gnus-uu-ask-before-view t)
- ;;
- ;; You can set this variable even if you're not using asynchronous
- ;; viewing, of course.
- ;;
- ;; If the articles has been posted by some numbscull with a PC (isn't
- ;; that a bit redundant, though?) and there's lots of carriage returns
- ;; everywhere, say
- ;;
- ;; (setq gnus-uu-kill-carriage-return t)
- ;;
- ;; If you want gnus-uu to ignore the default file rules when viewing,
- ;; for instance if there's several file types that you can't view, set
- ;; `gnus-uu-ignore-default-view-rules' to `t'. There's a similar
- ;; variable to disable the default unarchive rule list,
- ;; `gnus-uu-ignore-default-archive-rules'.
- ;;
- ;; If you want a more interactive approach to file viewing, say
- ;;
- ;; (setq gnus-uu-use-interactive-view t)
- ;;
- ;; If this variable is set, whenever you type `C-c C-v C-v' (or any of
- ;; the other view commands), gnus-uu will present you with a buffer
- ;; with the default actions and file names after decoding. You can
- ;; edit the command lines and execute them in a convenient fashion.
- ;; The output from the commands will be displayed in a small window at
- ;; the bottom of the emacs window. End interactive mode by typing `C-c
- ;; C-c' in the view window.
- ;;
- ;; If you want gnus-uu to unmark articles that you have asked to
- ;; decode, but can't be decoded (if, for instance, the articles aren't
- ;; uuencoded files or the posting is incomplete), say
- ;;
- ;; (setq gnus-uu-unmark-articles-not-decoded t)
- ;;
- ;;
- ;; History
- ;;
- ;; v1.0: First version released Oct 2 1992.
- ;;
- ;; v1.1: Changed `C-c C-r' to `C-c C-e' and `C-c C-p' to `C-c C-k'.
- ;; Changed (setq gnus-exit-group-hook) to (add-hook). Removed
- ;; checking for "Re:" for finding parts.
- ;;
- ;; v2.2: Fixed handling of currupted archives. Changed uudecoding to
- ;; an asynchronous process to avoid loading tons of data into emacs
- ;; buffers. No longer reads articles emacs already have aboard. Fixed
- ;; a firmer support for shar files. Made regexp searches for files
- ;; more convenient. Added `C-c C-l' for editing uucode begin
- ;; lines. Added multi-system decoder entry point. Added interactive
- ;; view mode. Added function for decoding and saving all uuencoded
- ;; articles in the current newsgroup.
- ;;
- ;; v2.3: After suggestions I have changed all the gnus-uu key bindings
- ;; to avoid hogging all the user keys (C-c LETTER). Also added
- ;; (provide) and fixed some saving stuff. First posted version to
- ;; gnu.emacs.sources.
- ;;
- ;;
- ;; Keymap overview:
- ;;
- ;; All commands start with `C-c C-v'. The difference is in the third
- ;; keystroke. All view commands are `C-LETTER'. All save commands are
- ;; just `LETTER'. All marked commands are the same as the unmarked
- ;; commands, except that they have `M-' before in the last keystroke.
- ;;
- ;; `C-c C-v C-v' gnus-uu-decode-and-view
- ;; `C-c C-v v' gnus-uu-decode-and-save
- ;; `C-c C-v C-s' gnus-uu-shar-and-view
- ;; `C-c C-v s' gnus-uu-shar-and-save
- ;; `C-c C-v C-m' gnus-uu-multi-decode-and-view
- ;; `C-c C-v m' gnus-uu-multi-decode-and-save
- ;;
- ;; `C-c C-v C-b' gnus-uu-decode-and-show-in-buffer
- ;; `C-c C-v a' gnus-uu-decode-and-save-all-articles
- ;; `C-c C-v C-l' gnus-uu-edit-begin-line
- ;;
- ;; `#' gnus-uu-mark-article
- ;; `M-#' gnus-uu-unmark-article
- ;; `C-c C-v C-u' gnus-uu-unmark-all-articles
- ;; `C-c C-v C-r' gnus-uu-mark-by-regexp
- ;; `C-c C-v M-C-v' gnus-uu-marked-decode-and-view
- ;; `C-c C-v M-v' gnus-uu-marked-decode-and-save
- ;; `C-c C-v M-C-s' gnus-uu-marked-shar-and-view
- ;; `C-c C-v M-s' gnus-uu-marked-shar-and-save
- ;; `C-c C-v M-C-m' gnus-uu-marked-multi-decode-and-view
- ;; `C-c C-v M-m' gnus-uu-marked-multi-decode-and-save
- ;;
- ;; `C-c C-v C-a' gnus-uu-toggle-asynchronous
- ;; `C-c C-v C-q' gnus-uu-toggle-query
- ;; `C-c C-v C-p' gnus-uu-toggle-always-ask
- ;; `C-c C-v C-k' gnus-uu-toggle-kill-carriage-return
- ;; `C-c C-v C-i' gnus-uu-toggle-interactive-view
- ;; `C-c C-v C-t' gnus-uu-toggle-any-variable
-
- (require 'gnus)
-
- ;; Binding of keys to the gnus-uu functions.
-
- (defvar gnus-uu-ctl-map nil)
- (define-prefix-command 'gnus-uu-ctl-map)
- (define-key gnus-summary-mode-map "\C-c\C-v" gnus-uu-ctl-map)
-
- (define-key gnus-uu-ctl-map "\C-v" 'gnus-uu-decode-and-view)
- (define-key gnus-uu-ctl-map "v" 'gnus-uu-decode-and-save)
- (define-key gnus-uu-ctl-map "\C-s" 'gnus-uu-shar-and-view)
- (define-key gnus-uu-ctl-map "s" 'gnus-uu-shar-and-save)
- (define-key gnus-uu-ctl-map "\C-m" 'gnus-uu-multi-decode-and-view)
- (define-key gnus-uu-ctl-map "m" 'gnus-uu-multi-decode-and-save)
-
- (define-key gnus-uu-ctl-map "\C-b" 'gnus-uu-decode-and-show-in-buffer)
-
- (define-key gnus-summary-mode-map "#" 'gnus-uu-mark-article)
- (define-key gnus-summary-mode-map "\M-#" 'gnus-uu-unmark-article)
- (define-key gnus-uu-ctl-map "\C-u" 'gnus-uu-unmark-all-articles)
- (define-key gnus-uu-ctl-map "\C-r" 'gnus-uu-mark-by-regexp)
-
- (define-key gnus-uu-ctl-map "\M-\C-v" 'gnus-uu-marked-decode-and-view)
- (define-key gnus-uu-ctl-map "\M-v" 'gnus-uu-marked-decode-and-save)
- (define-key gnus-uu-ctl-map "\M-\C-s" 'gnus-uu-marked-shar-and-view)
- (define-key gnus-uu-ctl-map "\M-s" 'gnus-uu-marked-shar-and-save)
- (define-key gnus-uu-ctl-map "\M-\C-m" 'gnus-uu-marked-multi-decode-and-view)
- (define-key gnus-uu-ctl-map "\M-m" 'gnus-uu-marked-multi-decode-and-save)
-
- (define-key gnus-uu-ctl-map "\C-a" 'gnus-uu-toggle-asynchronous)
- (define-key gnus-uu-ctl-map "\C-q" 'gnus-uu-toggle-query)
- (define-key gnus-uu-ctl-map "\C-p" 'gnus-uu-toggle-always-ask)
- (define-key gnus-uu-ctl-map "\C-k" 'gnus-uu-toggle-kill-carriage-return)
- (define-key gnus-uu-ctl-map "\C-i" 'gnus-uu-toggle-interactive-view)
- (define-key gnus-uu-ctl-map "\C-t" 'gnus-uu-toggle-any-variable)
-
- (define-key gnus-uu-ctl-map "\C-l" 'gnus-uu-edit-begin-line)
-
- (define-key gnus-uu-ctl-map "a" 'gnus-uu-decode-and-save-all-articles)
-
-
- ;; Default viewing actions
-
- (defconst gnus-uu-default-view-rules
- (list '("\\.\\(jpe?g$\\|gif$\\|tiff?$\\|p[pgb]m$\\|xwd$\\|xbm$\\)" "xv")
- '("\\.txt$\\|\\.doc$\\|read.*me" "xterm -e less")
- '("\\.fli$" "xflick")
- '("\\.\\(wav\\|aiff\\|hcom\\|u[blw]\\|s[bfw]\\|voc\\|smp\\)$"
- "sox %s -t .au - > /dev/audio")
- '("\\.au$" "cat %s > /dev/audio")
- '("\\.mod$" "str32")
- '("\\.ps$" "ghostview")
- '("\\.dvi$" "xdvi")
- '("\\.1$" "xterm -e man -l")
- '("\\.html$" "xmosaic")
- '("\\.mpe?g$" "mpeg_play")
- '("\\.\\(tar\\|arj\\|zip\\|zoo\\|arc\\|gz\\|Z\\|lzh\\|ar\\)$"
- "gnus-uu-archive"))
-
-
- "This constant is a list that gives the default actions to be taken
- when the user asks to view a file. To change the behaviour, you can
- either edit this constant or set 'gnus-uu-user-view-rules' to
- something useful. To add a default \"end\" rule, edit the
- 'gnus-uu-user-view-rules-end' variable.
-
- For example:
-
- To make gnus-uu use 'xli' to display JPEG and GIF files, put the following in
- your .emacs file
-
- (setq gnus-uu-user-view-rules (list '(\"jpg$\\\\|gif$\" \"xli\")))
-
- Both these variables are lists of lists of strings, where the first string
- is a regular expression. If the file name matches this regular expression,
- the command in the second string is fed the file.
-
- If the command string contains \"%s\", the file name will be inserted
- at that point in the command string. If there's no \"%s\" in the command
- string, the file name will be appended to the command before executing.
- ")
-
- (defvar gnus-uu-user-view-rules nil
- "User variable. See explanation of the 'gnus-uu-default-view-rules' for
- details.")
- (defvar gnus-uu-user-view-rules-end nil)
-
-
- ;; Default unpacking commands
-
- (defconst gnus-uu-default-archive-rules
- (list '("\\.tar$" "tar xf")
- '("\\.zip$" "unzip")
- '("\\.ar$" "ar x")
- '("\\.arj$" "unarj x")
- '("\\.zoo$" "zoo -e")
- '("\\.lzh$" "lha x")
- '("\\.Z$" "uncompress")
- '("\\.gz$" "gunzip")
- '("\\.arc$" "arc -x"))
- "*")
- (defvar gnus-uu-user-archive-rules nil)
-
-
- ;; Various variables
-
- (defconst gnus-uu-tmp-dir "/tmp/"
- "Variable saying where gnus-uu is to do its work.")
-
- (defconst gnus-uu-output-buffer-name "*Gnus UU Output*" "*")
- (defconst gnus-uu-result-buffer "*Gnus UU Result Buffer*" "*")
-
- (defvar gnus-uu-marked-article-list nil "*")
-
- (defvar gnus-uu-do-not-unpack-archives nil
- "Set this variable if you don't want gnus-uu to look inside
- archives for files to display.")
-
- (defvar gnus-uu-view-and-save nil
- "Set this variable if you want to be asked if you want to save the
- file after viewing. If this variable is nil, which is the default,
- gnus-uu won't offer to save a file if viewing is successful.")
-
- (defvar gnus-uu-asynchronous nil
- "Set this variable to `t' if you don't want gnus-uu to wait until
- the viewing command has ended before returning control to emacs.")
- (defvar gnus-uu-ask-before-view nil
- "Set this variable to `t' if you want gnus-uu to ask you before
- viewing every file. Useful when `gnus-uu-asynchronous' is set.")
-
- (defvar gnus-uu-ignore-default-view-rules nil
- "Set this variable if you want gnus-uu to ignore the default viewing
- rules and just use the rules given in gnus-uu-user-view-rules.")
-
- (defvar gnus-uu-ignore-default-archive-rules nil
- "Set this variable if you want gnus-uu to ignore the default archive
- unpacking commands and just use the rules given in
- gnus-uu-user-archive-rules.")
-
- (defvar gnus-uu-kill-carriage-return nil
- "Set this variable if you want to remove all carriage returns from
- the mail articles.")
-
- (defvar gnus-uu-generated-file-list nil)
-
- (defconst gnus-uu-uudecode-process nil)
-
- ;; Definition of uuencoded body etc.
-
- (defconst gnus-uu-begin-string "^begin[ \t]+[0-7][0-7][0-7][ \t]+\\(.*\\)$"
- "*")
- (defconst gnus-uu-end-string "^end[ \t]*$")
- (defconst gnus-uu-body-line
- "^M.............................................................?$" "*")
- (defconst gnus-uu-shar-begin-string "^#! */bin/sh" "*")
-
- (defvar gnus-uu-file-name nil)
-
- (defvar gnus-uu-shar-file-name nil "*")
- (defconst gnus-uu-shar-name-marker "begin [0-7][0-7][0-7][ \t]+\\(\\(\\w\\|\\.\\)*\\b\\)" "*")
- (defvar gnus-uu-shar-directory nil)
-
- (defvar gnus-uu-use-interactive-view nil)
- (defvar gnus-uu-interactive-file-list nil)
- (defconst gnus-uu-interactive-buffer-name "*gnus-uu interactive*")
-
- (defvar gnus-uu-unmark-articles-not-decoded nil)
-
- (defvar gnus-uu-output-window-height 14
- "This variable says how hight the output buffer window is to be when
- using interactive view mode. Change it at your convenience.")
-
- ;; Interactive functions
-
-
- (defun gnus-uu-decode-and-view ()
- "UUdecodes and 'views' (if possible) the resulting file.
- 'Viewing' can be any action at all, as defined in the
- 'gnus-uu-file-action-list' variable. Running 'xv' on gifs and
- 'play' on au files are popular actions. If the file can't be viewed,
- the user is asked if she would like to save the file instead."
- (interactive)
- (gnus-uu-decode-and-view-or-save t nil))
-
- (defun gnus-uu-decode-and-save ()
- "uudecodes and saves the resulting file."
- (interactive)
- (gnus-uu-decode-and-view-or-save nil nil))
-
- (defun gnus-uu-marked-decode-and-view ()
- "The marked equivalent to gnus-uu-decode-and-view."
- (interactive)
- (gnus-uu-decode-and-view-or-save t t))
-
- (defun gnus-uu-marked-decode-and-save ()
- "The marked equivalent to gnus-uu-decode-and-save."
- (interactive)
- (gnus-uu-decode-and-view-or-save nil nil))
-
-
- (defun gnus-uu-shar-and-view ()
- "Does the same as gnus-uu-decode-and-view for shar files."
- (interactive)
- (gnus-uu-unshar-and-view-or-save t nil))
-
- (defun gnus-uu-shar-and-save ()
- "Does the same as gnus-uu-decode-and-save for shar files."
- (interactive)
- (gnus-uu-unshar-and-view-or-save nil nil))
-
- (defun gnus-uu-marked-shar-and-view ()
- "The marked equivalent to gnus-uu-shar-and-view."
- (interactive)
- (gnus-uu-unshar-and-view-or-save t t))
-
- (defun gnus-uu-marked-shar-and-save ()
- "The marked equivalent to gnus-uu-shar-and-save."
- (interactive)
- (gnus-uu-unshar-and-view-or-save nil t))
-
-
- (defun gnus-uu-decode-and-show-in-buffer ()
- "uudecodes the current article and displays the result in a buffer."
- (interactive)
- (let ((uu-buffer (get-buffer-create gnus-uu-output-buffer-name))
- list-of-articles file-name)
- (save-excursion
-
- (and (setq list-of-articles (list gnus-current-article))
- (gnus-uu-grab-articles list-of-articles 'gnus-uu-uustrip-article-as)
- (setq file-name (gnus-uu-decode gnus-uu-tmp-dir))
- (progn
- (save-excursion
- (set-buffer uu-buffer)
- (erase-buffer)
- (insert-file-contents file-name))
- (set-window-buffer (get-buffer-window gnus-article-buffer)
- uu-buffer)
- (message (format "Showing file %s in buffer" file-name))
- (delete-file file-name))))))
-
-
- (defun gnus-uu-toggle-asynchronous ()
- "This function toggles asynchronous viewing."
- (interactive)
- (if (setq gnus-uu-asynchronous (not gnus-uu-asynchronous))
- (message "gnus-uu will now view files asynchronously")
- (message "gnus-uu will now view files synchronously")))
-
- (defun gnus-uu-toggle-query ()
- "This function toggles whether to ask before viewing or not."
- (interactive)
- (if (setq gnus-uu-ask-before-view (not gnus-uu-ask-before-view))
- (message "gnus-uu will now ask before viewing")
- (message "gnus-uu will now view without asking first")))
-
- (defun gnus-uu-toggle-always-ask ()
- "This function toggles whether to ask saving a file even after successful
- viewing."
- (interactive)
- (if (setq gnus-uu-view-and-save (not gnus-uu-view-and-save))
- (message "gnus-uu will now ask to save the file after viewing")
- (message "gnus-uu will now not ask to save after successful viewing")))
-
- (defun gnus-uu-toggle-interactive-view ()
- "This function toggles whether to use interactive view."
- (interactive)
- (if (setq gnus-uu-use-interactive-view (not gnus-uu-use-interactive-view))
- (message "gnus-uu will now use interactive view")
- (message "gnus-uu will now use non-interactive view")))
-
- (defun gnus-uu-toggle-unmark-undecoded ()
- "This function toggles whether to unmark articles not decoded."
- (interactive)
- (if (setq gnus-uu-unmark-articles-not-decoded
- (not gnus-uu-unmark-articles-not-decoded))
- (message "gnus-uu will now unmark articles not decoded")
- (message "gnus-uu will now not unmark articles not decoded")))
-
- (defun gnus-uu-toggle-kill-carriage-return ()
- "This function toggles the stripping of carriage returns from the articles."
- (interactive)
- (if (setq gnus-uu-kill-carriage-return (not gnus-uu-kill-carriage-return))
- (message "gnus-uu will now strip carriage returns")
- (message "gnus-uu won't strip carriage returns")))
-
- (defun gnus-uu-toggle-any-variable ()
- "This function ask what variable the user wants to toggle."
- (interactive)
- (let (rep)
- (message "(a)sync, (q)uery, (p)always ask, (k)ill carriage, (i)nteractive, (u)nmark")
- (setq rep (read-char))
- (if (= rep ?a)
- (gnus-uu-toggle-asynchronous))
- (if (= rep ?q)
- (gnus-uu-toggle-query))
- (if (= rep ?y)
- (gnus-uu-toggle-always-ask))
- (if (= rep ?c)
- (gnus-uu-toggle-kill-carriage-return))
- (if (= rep ?u)
- (gnus-uu-toggle-unmark-undecoded))
- (if (= rep ?t)
- (gnus-uu-toggle-interactive-view))))
-
-
- (defun gnus-uu-edit-begin-line ()
- "Edit the begin line of the current article."
- (interactive)
- (let (begin b buffer-read-only)
- (save-excursion
- (set-buffer gnus-article-buffer)
- (goto-line 1)
- (if (not (re-search-forward gnus-uu-begin-string nil t))
- (progn (message "No begin line in the current article") (sit-for 2))
- (beginning-of-line)
- (setq b (point))
- (end-of-line)
- (setq begin (buffer-substring b (point)))
- (setq begin (read-string "" begin))
- (setq buffer-read-only nil)
- (delete-region b (point))
- (insert-string begin)))))
-
- ;; Multi functions
-
- (defun gnus-uu-multi-decode-and-view ()
- "This function lets the user decide what method to use for decoding.
- Other than that, it's equivalent to the other decode-and-view functions."
- (interactive)
- (gnus-uu-multi-decode-and-view-or-save t nil))
-
- (defun gnus-uu-multi-decode-and-save ()
- "This function lets the user decide what method to use for decoding.
- Other than that, it's equivalent to the other decode-and-save functions."
- (interactive)
- (gnus-uu-multi-decode-and-view-or-save nil nil))
-
- (defun gnus-uu-marked-multi-decode-and-view ()
- "This function lets the user decide what method to use for decoding.
- Other than that, it's equivalent to the other marked decode-and-view
- functions."
- (interactive)
- (gnus-uu-multi-decode-and-view-or-save t t))
-
- (defun gnus-uu-marked-multi-decode-and-save ()
- "This function lets the user decide what method to use for decoding.
- Other than that, it's equivalent to the other marked decode-and-save
- functions."
- (interactive)
- (gnus-uu-multi-decode-and-view-or-save t t))
-
- (defun gnus-uu-multi-decode-and-view-or-save (view marked)
- (let (decode-type)
- (message "(u)udecode, (s)har, s(a)ve: ")
- (setq decode-type (read-char))
- (if (= decode-type ?
- ) (setq decode-type ?u))
- (if (= decode-type ?u)
- (gnus-uu-decode-and-view-or-save view marked)
- (if (= decode-type ?s)
- (gnus-uu-unshar-and-view-or-save view marked)
- (if (= decode-type ?a)
- (gnus-uu-save-articles view marked)
- (message (format "Unknown decode method '%c'." decode-type))
- (sit-for 2))))))
-
- ;; All files
- (defconst gnus-uu-rest-of-articles nil)
- (defconst gnus-uu-do-sloppy-uudecode nil)
- (defvar gnus-uu-current-save-dir nil "*")
-
- (defun gnus-uu-decode-and-save-all-articles ()
- "This function reads all unread aticles in the current group and
- sees whether it can uudecode the articles. The user will be prompted
- for an directory to put the resulting (if any) files."
- (interactive)
- (let ((gnus-uu-unmark-articles-not-decoded t)
- where dir did unmark)
- (setq gnus-uu-do-sloppy-uudecode t)
- (setq dir (gnus-uu-read-directory "Where do you want the files? "
- gnus-uu-current-save-dir))
- (setq gnus-uu-current-save-dir dir)
- (setq gnus-uu-rest-of-articles (gnus-uu-get-list-of-articles "^." t t))
- (setq gnus-uu-file-name nil)
- (while (and gnus-uu-rest-of-articles
- (gnus-uu-grab-articles gnus-uu-rest-of-articles
- 'gnus-uu-uustrip-article-as))
- (if gnus-uu-file-name
- (progn
- (rename-file (concat gnus-uu-tmp-dir gnus-uu-file-name)
- (concat dir gnus-uu-file-name) t)
- (setq did t)
- (setq gnus-uu-file-name nil))))
- (if did (message "Saved.")))
- (setq gnus-uu-do-sloppy-uudecode nil))
-
-
-
- ;; Work functions
-
- (defun gnus-uu-decode-and-view-or-save (view marked)
- (gnus-uu-initialize)
- (let (file decoded)
- (save-excursion
- (if (gnus-uu-decode-and-strip nil marked)
- (progn
- (setq decoded t)
- (setq file (concat gnus-uu-tmp-dir gnus-uu-file-name))
- (if view (gnus-uu-view-file file)
- (gnus-uu-save-file file)))))
-
- (gnus-summary-next-subject 1 t)
-
- (if (and gnus-uu-use-interactive-view view decoded)
- (gnus-uu-do-interactive))
-
- (if (or (not gnus-uu-use-interactive-view) (not decoded))
- (gnus-uu-clean-up))))
-
-
- (defun gnus-uu-unshar-and-view-or-save (view marked)
- "Unshars and views/saves marked/unmarked articles."
- (gnus-uu-initialize)
- (let (tar-file files decoded)
- (save-excursion
- (setq gnus-uu-shar-directory
- (make-temp-name (concat gnus-uu-tmp-dir "gnusuush")))
- (make-directory gnus-uu-shar-directory)
- (gnus-uu-add-file gnus-uu-shar-directory)
- (if (gnus-uu-decode-and-strip t marked)
- (progn
- (setq decoded t)
- (setq files (directory-files gnus-uu-shar-directory t))
- (setq gnus-uu-generated-file-list
- (append files gnus-uu-generated-file-list))
- (if (> (length files) 3)
- (progn
- (setq tar-file
- (concat
- (make-temp-name (concat gnus-uu-tmp-dir "gnusuuar"))
- ".tar"))
- (gnus-uu-add-file tar-file)
- (call-process "sh" nil
- (get-buffer-create gnus-uu-output-buffer-name)
- nil "-c"
- (format "cd %s ; tar cf %s * ; cd .. ; rm -r %s"
- gnus-uu-shar-directory
- tar-file
- gnus-uu-shar-directory))
- (if view
- (gnus-uu-view-file tar-file)
- (gnus-uu-save-file tar-file)))
- (if view
- (gnus-uu-view-file (elt files 2))
- (gnus-uu-save-file (elt files 2)))))))
-
- (gnus-summary-next-subject 1 t)
-
- (if (and gnus-uu-use-interactive-view view decoded)
- (gnus-uu-do-interactive))
-
- (if (or (not gnus-uu-use-interactive-view) (not decoded))
- (gnus-uu-clean-up))))
-
-
-
- (defconst gnus-uu-saved-article-name nil)
- (defun gnus-uu-save-articles (view marked)
- (let (list-of-articles)
- (save-excursion
- (if (not marked)
- (setq list-of-articles (gnus-uu-get-list-of-articles))
- (setq list-of-articles (reverse gnus-uu-marked-article-list))
- (setq gnus-uu-marked-article-list nil))
- (if (not list-of-articles)
- (progn
- (message "No list of articles")
- (sit-for 2))
- (setq gnus-uu-saved-article-name
- (concat gnus-uu-tmp-dir
- (read-file-name "Enter file name: " gnus-newsgroup-name
- gnus-newsgroup-name)))
- (gnus-uu-add-file gnus-uu-saved-article-name)
- (if (gnus-uu-grab-articles list-of-articles 'gnus-uu-save-article)
- (gnus-uu-save-file gnus-uu-saved-article-name))
- ))))
-
- (defun gnus-uu-save-article (buffer in-state)
- (save-excursion
- (set-buffer buffer)
- (call-process-region
- 1 (point-max) "sh" nil (get-buffer-create gnus-uu-output-buffer-name)
- nil "-c" (concat "cat >> " gnus-uu-saved-article-name)))
- 'ok)
-
- (defun gnus-uu-view-file (file-name &optional dont-ask)
- "This function takes two parameters. The first is name of the file to be
- viewed. gnus-uu-view-file will look for an action associated with the file
- type of the file. If it finds an appropriate action, the file will be
- attempted displayed.
-
- The second parameter specifies if the user is to be asked whether to
- save the file if viewing is unsuccessful. `t' means 'do not ask.'
-
- Note that the file given will be deleted by this function, one way or
- another. If `gnus-uu-asynchronous' is set, it won't be deleted right
- away, but sometime later. If the user is offered to save the file, it'll
- be moved to wherever the user wants it.
-
- gnus-uu-view-file returns `t' if viewing is successful."
- (let (action did-view
- (didnt-want t)
- (do-view t))
- (setq action (gnus-uu-choose-action
- file-name
- (append gnus-uu-user-view-rules
- (if gnus-uu-ignore-default-view-rules
- nil
- gnus-uu-default-view-rules)
- gnus-uu-user-view-rules-end)))
-
- (if (and gnus-uu-use-interactive-view
- (not (string= (or action "") "gnus-uu-archive")))
- (gnus-uu-enter-interactive-file (or action "") file-name)
-
- (if action
- (if (string= action "gnus-uu-archive")
- (setq did-view (gnus-uu-treat-archive file-name))
-
- (if gnus-uu-ask-before-view
- (setq didnt-want
- (or (not
- (setq do-view
- (y-or-n-p
- (format "Do you want to view %s? "
- file-name))))
- didnt-want)))
-
- (if do-view
- (setq did-view
- (if gnus-uu-asynchronous
- (gnus-uu-call-asynchronous file-name action)
- (gnus-uu-call-synchronous file-name action))))))
-
- (if (and (not dont-ask) (not gnus-uu-use-interactive-view))
- (progn
- (if (and
- didnt-want
- (or (not action)
- (and (string= action "gnus-uu-archive") (not did-view))))
- (progn
- (message (format "Could find no rule for %s" file-name))
- (sit-for 2)))
- (and (or (not did-view) gnus-uu-view-and-save)
- (y-or-n-p
- (format "Do you want to save the file %s? " file-name))
- (gnus-uu-save-file file-name))))
-
- (if (and (file-exists-p file-name)
- (not gnus-uu-use-interactive-view)
- (or
- (not (and gnus-uu-asynchronous did-view))
- (string= action "gnus-uu-archive")))
- (delete-file file-name)))
-
- did-view))
-
-
- (defun gnus-uu-call-synchronous (file-name action)
- "Takes two parameters: The name of the file to be displayed and
- the command to display it with. Returns `t' on success and `nil' if
- the file couldn't be displayed."
- (let (did-view command)
- (save-excursion
- (set-buffer (get-buffer-create gnus-uu-output-buffer-name))
- (erase-buffer)
- (if (string-match "%s" action)
- (setq command (format action file-name))
- (setq command (concat action " " file-name)))
- (message (format "Viewing with '%s'" command))
- (if (not (= 0 (call-process "sh" nil t nil "-c" command)))
- (progn
- (goto-char 1)
- (while (re-search-forward "\n" nil t)
- (replace-match " "))
- (message (concat "Error: " (buffer-substring 1 (point-max))))
- (sit-for 2))
- (message "")
- (setq did-view t)))
- did-view))
-
-
- (defun gnus-uu-call-asynchronous (file-name action)
- "Takes two parameters: The name of the file to be displayed and
- the command to display it with. Since the view command is executed
- asynchronously, it's kinda hard to decide whether the command succeded
- or not, so this function always returns `t'. It also adds \"; rm -f
- file-name\" to the end of the execution string, so the file will be
- removed after viewing has ended."
- (let (command file tmp-file start)
- (while (string-match "/" file-name start)
- (setq start (1+ (match-beginning 0))))
- (setq file (substring file-name start))
- (setq tmp-file (concat gnus-uu-tmp-dir file))
- (if (string= tmp-file file-name)
- ()
- (rename-file file-name tmp-file t)
- (setq file-name tmp-file))
-
- (if (string-match "%s" action)
- (setq command (format action file-name))
- (setq command (concat action " " file-name)))
- (setq command (format "%s ; rm -f %s" command file-name))
- (message (format "Viewing with %s" command))
- ; (sit-for 4)
- (start-process "gnus-uu-view"
- nil "sh" "-c" command)
- t))
-
-
- (defun gnus-uu-decode-and-strip (&optional shar use-marked)
- "This function does all the main work. It finds out what articles
- to grab, grabs them, strips the result and decodes. If any of
- these operations fail, it returns `nil', `t' otherwise.
- If shar is `t', it will pass this on to gnus-uu-grab-articles
- who will (probably) unshar the articles. If use-marked
- is non-nil, it won't try to find articles, but use the marked list."
- (let (list-of-articles)
- (save-excursion
-
- (if use-marked
- (progn (if (eq gnus-uu-marked-article-list ())
- (message "No articles marked")
- (setq list-of-articles (reverse gnus-uu-marked-article-list))
- (gnus-uu-unmark-all-articles)))
- (setq list-of-articles (gnus-uu-get-list-of-articles)))
-
- (and list-of-articles
- (gnus-uu-grab-articles list-of-articles
- (if shar
- 'gnus-uu-unshar-article
- 'gnus-uu-uustrip-article-as))))))
-
-
- (defun gnus-uu-reginize-string (string)
- "Takes a string and puts a \\ in front of every special character;
- ignores any leading \"version numbers\"
- thingies that they use in the comp.binaries groups, and either replaces
- anything that looks like \"2/3\" with \"[0-9]+/[0-9]+\" or, if it can't find
- something like that, replaces the last two numbers with \"[0-9]+\". This,
- in my experience, should get most postings of a series."
- (let ((count 2)
- reg)
- (save-excursion
- (set-buffer (get-buffer-create gnus-uu-output-buffer-name))
- (erase-buffer)
- (insert string)
-
- (goto-char 1)
- (while (re-search-forward "[\\[\\^\\+\\\\\\?\\$\\.\\*]" nil t)
- (backward-char)
- (insert "\\")
- (forward-char))
-
- (goto-char 1)
- (if (looking-at "[a-z][a-zA-Z0-9]*: ?")
- (replace-match "[a-z][a-zA-Z0-9]*: ?" nil nil))
-
- (goto-char 1)
- (while (re-search-forward "[ \t]+" nil t)
- (replace-match "[ \\t]+"))
-
- (goto-char 1)
- (if (re-search-forward "[0-9]+/[0-9]+" nil t)
- (replace-match "[0-9]+/[0-9]+")
-
- (goto-char 1)
- (if (re-search-forward "[0-9]+ *of *[0-9]+" nil t)
- (replace-match "[0-9]+ *of *[0-9]+")
-
- (end-of-line)
- (while (and (re-search-backward "[0-9]" nil t) (> count 0))
- (while (looking-at "[0-9]")
- (backward-char))
- (re-search-forward "[0-9]+" nil t)
- (replace-match "[0-9]+")
- (backward-char 5)
- (setq count (1- count)))))
- ; (message (format "reg er %s" (buffer-substring 1 (point-max))))
- ; (sit-for 4)
- (buffer-substring 1 (point-max)))))
-
-
- (defun gnus-uu-get-list-of-articles (&optional subject mark-articles only-unread)
- "Finds all articles that matches the regular expression given.
- Returns the resulting list."
- (let (beg end reg-subject list-of-subjects list-of-numbers art-num)
- (save-excursion
-
- ; If the subject is not given, this function looks at the current subject
- ; and takes that.
-
- (if subject
- (setq reg-subject subject)
- (end-of-line)
- (setq end (point))
- (beginning-of-line)
- (if (not (re-search-forward "\\] " end t))
- (progn (message "No valid subject chosen") (sit-for 2))
- (setq subject (buffer-substring (point) end))
- (setq reg-subject (concat
- "\\[.*\\] "
- (gnus-uu-reginize-string subject)))))
-
- (if reg-subject
- (progn
-
- ; Collect all subjects matching reg-subject.
-
- (goto-char 1)
- (while (re-search-forward reg-subject nil t)
- (beginning-of-line)
- (setq beg (point))
- (if (or (not only-unread) (looking-at " \\|-"))
- (progn
- (end-of-line)
- (setq list-of-subjects (cons (buffer-substring beg (point))
- list-of-subjects)))
- (end-of-line)))
-
-
- ; Expand all numbers in all the subjects: (hi9 -> hi0009, etc).
-
- (setq list-of-subjects (gnus-uu-expand-numbers list-of-subjects))
-
- ; Sort the subjects.
-
- (setq list-of-subjects (sort list-of-subjects 'gnus-uu-string<))
-
- ; Get the article numbers from the sorted list of subjects.
-
- (while (not (eq list-of-subjects ()))
- (setq art-num (gnus-uu-article-number (car list-of-subjects)))
- (if mark-articles (gnus-summary-mark-as-read art-num ?#))
- (setq list-of-numbers (cons art-num list-of-numbers))
- (setq list-of-subjects (cdr list-of-subjects)))
-
- (setq list-of-numbers (reverse list-of-numbers))
-
- (if (eq list-of-numbers ())
- (progn
- (message (concat "No subjects matched " subject))
- (sit-for 2)))))
-
- list-of-numbers)))
-
-
- (defun gnus-uu-expand-numbers (string-list)
- "Takes a list of strings and \"expands\" all numbers in all the strings.
- That is, this function makes all numbers equal length by prepending lots
- of zeroes before each number. This is to ease later sorting to find out
- what sequence the articles are supposed to be decoded in. Returns the list
- of expanded strings."
- (let (string out-list pos num)
- (while (not (eq string-list ()))
- (setq string (car string-list))
- (setq string-list (cdr string-list))
- (setq pos (string-match "\\] " string))
- (while (string-match "\\([^0-9]*\\|^\\)\\([0-9]+\\)\\([^0-9]\\|$\\)"
- string pos)
- (setq num (- 6 (- (match-end 2) (match-beginning 2))))
- (setq string
- (format "%s%06d%s"
- (substring string 0 (match-beginning 2))
- (string-to-int (substring string
- (match-beginning 2)
- (match-end 2)))
- (substring string (match-end 2))))
- (setq pos (+ (match-end 2) num)))
- (setq out-list (cons string out-list)))
- out-list))
-
-
- (defun gnus-uu-string< (string1 string2)
- "Used in a sort for finding out what string is bigger, but ignoring
- everything before the subject part."
- (string< (substring string1 (string-match "\\] " string1))
- (substring string2 (string-match "\\] " string2))))
-
-
- ;; gnus-uu-grab-article
- ;;
- ;; This is the general multi-article treatment function.
- ;; It takes a list of articles to be grabbed and a function
- ;; to apply to each article. It puts the result in
- ;; gnus-uu-result-buffer.
- ;;
- ;; The function to be called should take two parameters.
- ;; The first is the buffer that has the article that should
- ;; be treated. The function should leave the result in this
- ;; buffer as well. This result is then appended on to the
- ;; gnus-uu-result-buffer.
- ;; The second parameter is the state of the list of articles,
- ;; and can have three values: 'start, 'middle and 'end.
- ;; The function can have several return values.
- ;; 'error if there was an error while treating.
- ;; 'end if the last article has been sighted.
- ;; 'begin-and-end if the article is both the beginning and
- ;; the end. All these three return values results in
- ;; gnus-uu-grab-articles stopping traversing of the list
- ;; of articles.
- ;; 'middle if the article is a "middle" article.
- ;; 'ok if everything is ok.
-
- (defvar gnus-uu-has-been-grabbed nil)
-
- (defun gnus-uu-unmark-list-of-grabbed (&optional dont-unmark-last-article)
- (let (art)
- (if (or (not gnus-uu-has-been-grabbed)
- (not gnus-uu-unmark-articles-not-decoded))
- ()
- (if dont-unmark-last-article
- (progn
- (setq art (car gnus-uu-has-been-grabbed))
- (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed))))
- (while gnus-uu-has-been-grabbed
- (gnus-summary-mark-as-unread (car gnus-uu-has-been-grabbed) t)
- (setq gnus-uu-has-been-grabbed (cdr gnus-uu-has-been-grabbed)))
- (if dont-unmark-last-article
- (setq gnus-uu-has-been-grabbed (list art)))
- )))
-
-
- (defun gnus-uu-grab-articles (list-of-articles process-function)
- "This function takes a list of articles and a function to apply
- to each article grabbed. The result of the function is appended
- on to gnus-uu-result-buffer.
-
- This function returns `t' if the grabbing and the process-function
- has been successful and `nil' otherwise."
- (let ((result-buffer (get-buffer-create gnus-uu-result-buffer))
- (state 'first)
- (process-state 'ok)
- (result t)
- (wrong-type t)
- (has-been-begin nil)
- (article nil))
-
- (save-excursion
- (set-buffer result-buffer)
- (erase-buffer))
- (setq gnus-uu-has-been-grabbed nil)
- (while (and (not (eq list-of-articles ()))
- (not (eq process-state 'end))
- (not (eq process-state 'begin-and-end))
- (not (eq process-state 'error)))
- (setq article (car list-of-articles))
- (setq list-of-articles (cdr list-of-articles))
- (setq gnus-uu-has-been-grabbed (cons article gnus-uu-has-been-grabbed))
-
- (if (eq list-of-articles ()) (setq state 'last))
-
- (message (format "Getting article %d" article))
- ; (sit-for 2)
- (if (not (= (or gnus-current-article 0) article))
- (gnus-summary-display-article article))
- (gnus-summary-mark-as-read article)
-
- (save-excursion
- (set-buffer gnus-article-buffer)
- (widen))
-
- (setq process-state (funcall process-function gnus-article-buffer state))
-
- (if (eq process-state 'begin)
- (setq has-been-begin t))
-
- (if (not (eq process-state 'wrong-type))
- (setq wrong-type nil)
- (if gnus-uu-unmark-articles-not-decoded
- (gnus-summary-mark-as-unread article t)))
-
- (if gnus-uu-do-sloppy-uudecode
- (setq wrong-type nil))
-
- (if (and (not has-been-begin)
- (not gnus-uu-do-sloppy-uudecode)
- (or (eq process-state 'end)
- (eq process-state 'middle)))
- (progn
- (setq process-state 'error)
- (message "No begin part at the beginning")
- (sit-for 2))
- (setq state 'middle)))
-
- (if (and wrong-type (not gnus-uu-do-sloppy-uudecode))
- (progn
- (setq result nil)
- (message "Wrong type file")
- (sit-for 2))
- (if (eq process-state 'error)
- (setq result nil)
- (if (not (or (eq process-state 'ok)
- (eq process-state 'end)
- (eq process-state 'begin-and-end)))
- (progn
- (if (not gnus-uu-do-sloppy-uudecode)
- (progn
- (message "End of articles reached before end of file")
- (sit-for 2)))
- (gnus-uu-unmark-list-of-grabbed)
- (setq result nil)))))
- (setq gnus-uu-rest-of-articles list-of-articles)
- result))
-
- (defun gnus-uu-uustrip-article-as (process-buffer in-state)
- (let ((state 'ok)
- (process-connection-type nil)
- start-char pst)
- (save-excursion
- (set-buffer process-buffer)
-
- (goto-char 1)
-
- (if gnus-uu-kill-carriage-return
- (progn
- (while (re-search-forward "
- " nil t)
- (replace-match ""))
- (goto-char 1)))
-
- (if (not (re-search-forward
- (concat gnus-uu-begin-string "\\|" gnus-uu-body-line) nil t))
- (setq state 'wrong-type)
-
- (beginning-of-line)
- (setq start-char (point))
-
- (if (looking-at gnus-uu-begin-string)
- (progn
- (setq gnus-uu-file-name
- (buffer-substring (match-beginning 1) (match-end 1)))
- (setq pst (process-status (or gnus-uu-uudecode-process "")))
- (if (or (eq pst 'stop)
- (eq pst 'run))
- (progn
- (delete-process gnus-uu-uudecode-process)
- (gnus-uu-unmark-list-of-grabbed t)))
- (setq gnus-uu-uudecode-process
- (start-process
- "*uudecode*"
- (get-buffer-create gnus-uu-output-buffer-name)
- "sh" "-c"
- (format "cd %s ; uudecode" gnus-uu-tmp-dir)))
- (setq state 'begin)
- (setq gnus-uu-generated-file-list
- (cons (concat gnus-uu-tmp-dir gnus-uu-file-name)
- gnus-uu-generated-file-list)))
- (setq state 'middle))
-
- (goto-char (point-max))
- (re-search-backward
- (concat gnus-uu-body-line "\\|" gnus-uu-end-string) nil t)
- (if (looking-at gnus-uu-end-string)
- (if (eq state 'begin)
- (setq state 'begin-and-end)
- (setq state 'end)))
- (forward-line 1)
-
- (setq pst (process-status (or gnus-uu-uudecode-process "")))
- (if (or (eq pst 'run) (eq pst 'stop))
- (process-send-region
- gnus-uu-uudecode-process start-char (point))
- (setq state 'wrong-type))))
- state))
-
-
- (defun gnus-uu-unshar-article (process-buffer in-state)
- "This function is used by gnus-uu-grab-articles to treat
- a shared article."
- (let ((state 'ok)
- start-char)
- (save-excursion
- (set-buffer process-buffer)
- (goto-char 1)
- (if (not (re-search-forward gnus-uu-shar-begin-string nil t))
- (setq state 'wrong-type)
- (beginning-of-line)
- (setq start-char (point))
- (call-process-region start-char (point-max) "sh" nil
- (get-buffer-create gnus-uu-output-buffer-name) nil "-c"
- (concat "cd " gnus-uu-shar-directory " ; sh"))))
- state))
-
-
- (defun gnus-uu-find-name-in-shar ()
- "Returns the name of what the shar file is going to unpack."
- (let ((oldpoint (point))
- res)
- (goto-char 1)
- (if (re-search-forward gnus-uu-shar-name-marker nil t)
- (setq res (buffer-substring (match-beginning 1) (match-end 1))))
- (goto-char oldpoint)
- res))
-
-
- (defun gnus-uu-article-number (subject)
- "Returns the article number of the given subject."
- (let (end)
- (string-match "[0-9]+[^0-9]" subject 1)
- (setq end (match-end 0))
- (string-to-int
- (substring subject (string-match "[0-9]" subject 1) end))))
-
-
- (defun gnus-uu-decode (directory)
- "UUdecodes everything in the buffer and returns the name of the resulting
- file."
- (let ((command (concat "cd " directory " ; uudecode"))
- file-name)
- (save-excursion
- (message "Uudecoding...")
- (set-buffer (get-buffer-create gnus-uu-result-buffer))
- (setq file-name (concat gnus-uu-tmp-dir gnus-uu-file-name))
- (gnus-uu-add-file file-name)
- (call-process-region 1 (point-max) "sh" nil t nil "-c" command)
- file-name)))
-
-
- (defun gnus-uu-choose-action (file-name file-action-list)
- "Chooses what action to perform given the name and gnus-uu-file-action-list.
- Returns either nil if no action is found, or the name of the command
- to run if such a rule is found."
- (let ((action-list (copy-sequence file-action-list))
- rule action)
- (while (not (or (eq action-list ()) action))
- (setq rule (car action-list))
- (setq action-list (cdr action-list))
- (if (string-match (car rule) file-name)
- (setq action (car (cdr rule)))))
- action))
-
-
- (defun gnus-uu-save-file (from-file-name &optional default-dir ignore-existing)
- "Moves the file from the tmp directory to where the user wants it."
- (let (dir file-name command)
- (string-match "/[^/]*$" from-file-name)
- (setq file-name (substring from-file-name (1+ (match-beginning 0))))
- (if default-dir
- (setq dir default-dir)
- (setq dir (gnus-uu-read-directory "Where do you want the file? "
- gnus-uu-current-save-dir))
- (setq gnus-uu-current-save-dir dir))
- (if (and (not ignore-existing) (file-exists-p (concat dir file-name)))
- (progn
- (message (concat "There already is a file called " file-name))
- (sit-for 2)
- (setq file-name
- (read-file-name "Give a new name: " dir (concat dir file-name)
- nil file-name)))
- (setq file-name (concat dir file-name)))
- (rename-file from-file-name file-name t)))
-
-
-
- ;; reading a directory name, and offering to create if it doesn't exist.
- ;; Taken from gnus-mark
-
- (defun gnus-uu-read-directory (prompt &optional default-dir)
- (let ((dir
- (read-file-name prompt
- (or default-dir default-directory)
- (or default-dir default-directory))))
- (if (string-match "/$" dir)
- (setq dir (substring dir 0 (match-beginning 0))))
- (setq dir
- (cond ((file-directory-p dir) dir)
- ((file-exists-p dir)
- (ding)
- (message "%s exists and is not a directory!" dir)
- (sleep-for 2)
- (gnus-uu-read-directory prompt dir))
- ((y-or-n-p (format "directory %s doesn't exist, create it? " dir))
- (make-directory dir)
- dir)
- (t (gnus-uu-read-directory prompt dir))))
- (if (string-match "/$" dir)
- dir
- (concat dir "/"))))
-
-
- (defun gnus-uu-treat-archive (file-name)
- "Unpacks an archive and views all the files in it. Returns `t' if
- viewing one or more files is successful."
- (let ((arc-dir (make-temp-name
- (concat gnus-uu-tmp-dir "gnusuu")))
- action command files file did-view short-file-name
- error-during-unarching)
- (setq action (gnus-uu-choose-action
- file-name (append gnus-uu-user-archive-rules
- (if gnus-uu-ignore-default-archive-rules
- nil
- gnus-uu-default-archive-rules))))
- (if (not action)
- (progn (message (format "No unpackers for the file %s" file-name))
- (sit-for 2))
- (string-match "/[^/]*$" file-name)
- (setq short-file-name (substring file-name (1+ (match-beginning 0))))
- (setq command (format "mv %s %s ; cd %s ; %s %s "
- file-name arc-dir
- arc-dir
- action short-file-name ))
- (make-directory arc-dir)
- (setq gnus-uu-generated-file-list
- (cons arc-dir gnus-uu-generated-file-list))
-
- (save-excursion
- (set-buffer (get-buffer-create gnus-uu-output-buffer-name))
- (erase-buffer))
-
- (message (format "Unpacking with %s..." action))
-
- (if (= 0 (call-process "sh" nil
- (get-buffer-create gnus-uu-output-buffer-name)
- nil "-c" command))
- (message "")
- (message "Error during unpacking of archive")
- (sit-for 2)
- (sit-for 2)
- (setq error-during-unarching t))
-
- (call-process "sh" nil (get-buffer gnus-uu-output-buffer-name)
- nil "-c" (format "mv %s/%s %s" arc-dir short-file-name
- gnus-uu-tmp-dir))
-
- (setq did-view (or (gnus-uu-show-directory
- arc-dir gnus-uu-use-interactive-view) did-view))
-
- (if (and (not gnus-uu-use-interactive-view)
- (file-directory-p arc-dir))
- (delete-directory arc-dir)))
-
- did-view))
-
-
- (defun gnus-uu-show-directory (dir &optional dont-delete-files)
- "Tries to view all the files in the given directory. Returns `t' if
- viewing one or more files is successful."
- (let (files file did-view)
- (setq files (directory-files dir t))
- (setq gnus-uu-generated-file-list
- (append files gnus-uu-generated-file-list))
- (while (not (eq files ()))
- (setq file (car files))
- (setq files (cdr files))
- (if (and (not (string-match "/\\.$" file))
- (not (string-match "/\\.\\.$" file)))
- (progn
- (if (file-directory-p file)
- (setq did-view (or (gnus-uu-show-directory file
- dont-delete-files)
- did-view))
- (setq did-view (or (gnus-uu-view-file file t) did-view))
- (if (and (not dont-delete-files) (file-exists-p file))
- (delete-file file))))))
- (if (not dont-delete-files) (delete-directory dir))
- did-view))
-
- ;; Manual choosing stuff
-
- (defun gnus-uu-enter-mark-in-list ()
- (let (article beg)
- (beginning-of-line)
- (setq beg (point))
- (end-of-line)
- (setq article (gnus-uu-article-number
- (buffer-substring beg (point))))
- (message (format "Adding article %d to list" article))
- (setq gnus-uu-marked-article-list
- (cons article gnus-uu-marked-article-list))))
-
- (defun gnus-uu-mark-article ()
- "Marks the current article to be decoded later."
- (interactive)
- (gnus-uu-enter-mark-in-list)
- (gnus-summary-mark-as-read nil ?#)
- (gnus-summary-next-subject 1 nil))
-
- (defun gnus-uu-unmark-article ()
- "Unmarks the current article."
- (interactive)
- (let ((in (copy-sequence gnus-uu-marked-article-list))
- out article beg found
- (old-point (point)))
- (beginning-of-line)
- (setq beg (point))
- (end-of-line)
- (setq article (gnus-uu-article-number (buffer-substring beg (point))))
- (message (format "Removing article %d" article))
- (while (not (eq in ()))
- (if (not (= (car in) article))
- (setq out (cons (car in) out))
- (setq found t)
- (message (format "Removing article %d" article)))
- (setq in (cdr in)))
- (if (not found) (message "Not a marked article."))
- (setq gnus-uu-marked-article-list (reverse out))
- (gnus-summary-mark-as-unread nil t)
- (gnus-summary-next-subject 1 nil)))
-
-
- (defun gnus-uu-unmark-all-articles ()
- "Removes the mark from all articles marked for decoding."
- (interactive)
- (let ((articles (copy-sequence gnus-uu-marked-article-list)))
- (while (not (eq articles ()))
- (gnus-summary-goto-subject (car articles))
- (gnus-summary-mark-as-unread nil t)
- (setq articles (cdr articles)))
- (setq gnus-uu-marked-article-list ())
- ))
-
-
-
-
- (defun gnus-uu-mark-by-regexp ()
- "Asks for a regular expression and marks all articles that match for later decoding."
- (interactive)
- (let (exp)
- (setq exp (read-from-minibuffer "Enter regular expression: "))
- (setq gnus-uu-marked-article-list
- (reverse (gnus-uu-get-list-of-articles exp t)))
- (message "")))
-
-
- ;; Various
-
- (defun gnus-uu-initialize ()
- (if (not gnus-uu-use-interactive-view)
- ()
- (save-excursion
- (setq gnus-uu-interactive-file-list nil)
- (set-buffer (get-buffer-create gnus-uu-interactive-buffer-name))
- (erase-buffer)
- (gnus-uu-mode)
- (insert
- "# Press return to execute a command.
- # Press `C-c C-c' to exit interactive view.
-
- ")
- )))
-
- (defun gnus-uu-clean-up ()
- "Kills the temporary uu buffers."
- (let (buf pst)
- (setq gnus-uu-do-sloppy-uudecode nil)
- (setq pst (process-status (or gnus-uu-uudecode-process "")))
- (if (or (eq pst 'stop)
- (eq pst 'run))
- (delete-process gnus-uu-uudecode-process))
- (and (setq buf (get-buffer gnus-uu-output-buffer-name))
- (kill-buffer buf))
- (and (setq buf (get-buffer gnus-uu-result-buffer))
- (kill-buffer buf))))
-
-
- (defun gnus-uu-check-for-generated-files ()
- "Deletes any generated files that hasn't been deleted, if, for
- instance, the user terminated decoding with `C-g'."
- (let (file)
- (while (not (eq gnus-uu-generated-file-list ()))
- (setq file (car gnus-uu-generated-file-list))
- (setq gnus-uu-generated-file-list (cdr gnus-uu-generated-file-list))
- (if (not (string-match "/\\.[\\.]?" file))
- (progn
- (if (file-directory-p file)
- (delete-directory file)
- (if (file-exists-p file)
- (delete-file file))))))))
-
- (defun gnus-uu-get-current-dir (&optional prompt)
- (setq gnus-uu-current-save-dir
- (gnus-uu-read-directory
- (if prompt prompt "Where do you want the file? ")
- gnus-uu-current-save-dir)))
-
- (defun gnus-uu-add-file (file)
- (setq gnus-uu-generated-file-list
- (cons file gnus-uu-generated-file-list)))
-
-
- ;; Initializing
-
-
- (add-hook 'gnus-exit-group-hook
- '(lambda ()
- (gnus-uu-clean-up)
- (setq gnus-uu-marked-article-list nil)
- (gnus-uu-check-for-generated-files)))
-
- (let (i)
- (setq gnus-uu-body-line "^M")
- (setq i 61)
- (while (> i 0)
- (setq gnus-uu-body-line (concat gnus-uu-body-line "."))
- (setq i (1- i)))
- (setq gnus-uu-body-line (concat gnus-uu-body-line "?$")))
-
-
-
- ;; Interactive exec mode
-
- (defvar gnus-uu-output-window nil)
-
- (defun gnus-uu-do-interactive ()
- (let (int-buffer out-buf)
- (set-buffer
- (setq int-buffer (get-buffer gnus-uu-interactive-buffer-name)))
- (switch-to-buffer-other-window int-buffer)
- (pop-to-buffer int-buffer)
- (setq gnus-uu-output-window
- (split-window nil (- (window-height) gnus-uu-output-window-height)))
- (set-window-buffer gnus-uu-output-window
- (setq out-buf
- (get-buffer-create gnus-uu-output-buffer-name)))
- (save-excursion (set-buffer out-buf) (erase-buffer))
- (goto-char 1)
- (forward-line 3)))
-
- (defun gnus-uu-enter-interactive-file (action file)
- (let (command)
- (save-excursion
- (setq gnus-uu-interactive-file-list
- (cons file gnus-uu-interactive-file-list))
- (set-buffer (get-buffer gnus-uu-interactive-buffer-name))
- (if (string-match "%s" action)
- (setq command (format action file))
- (setq command (concat action " " file)))
-
- (insert (format "%s\n" command)))))
-
- (defun gnus-uu-interactive-execute ()
- (interactive)
- (let (beg out-buf command)
- (beginning-of-line)
- (setq beg (point))
- (end-of-line)
- (setq command (buffer-substring beg (point)))
- (setq out-buf (get-buffer-create gnus-uu-output-buffer-name))
- (save-excursion
- (set-buffer out-buf)
- (erase-buffer)
- (insert (format "$ %s \n" command)))
- (message "Executing...")
- (if gnus-uu-asynchronous
- (start-process "gnus-uu-view" out-buf "sh" "-c" command)
- (call-process "sh" nil out-buf nil "-c" command)
- (message ""))
- (forward-line 1)
- (beginning-of-line)
- ))
-
- (defconst gnus-uu-mode-map nil "")
-
- (defun gnus-uu-interactive-end ()
- "This function ends interactive view mode and returns to summary mode."
- (interactive)
- (let (buf)
- (delete-window gnus-uu-output-window)
- (gnus-uu-clean-up)
- (gnus-uu-check-for-generated-files)
- (setq buf (get-buffer gnus-uu-interactive-buffer-name))
- (if gnus-article-buffer (switch-to-buffer gnus-article-buffer))
- (if buf (kill-buffer buf))
- (pop-to-buffer gnus-summary-buffer)))
-
- (if gnus-uu-mode-map
- ()
- (setq gnus-uu-mode-map (make-sparse-keymap))
- (define-key gnus-uu-mode-map "\C-c\C-x" 'gnus-uu-interactive-execute)
- (define-key gnus-uu-mode-map "\C-c\C-v" 'gnus-uu-interactive-execute)
- (define-key gnus-uu-mode-map "\C-m" 'gnus-uu-interactive-execute)
- (define-key gnus-uu-mode-map "\C-c\C-c" 'gnus-uu-interactive-end)
- (define-key gnus-uu-mode-map "\C-cs"
- 'gnus-uu-interactive-save-current-file)
- (define-key gnus-uu-mode-map "\C-c\C-s"
- 'gnus-uu-interactive-save-current-file-silent)
- (define-key gnus-uu-mode-map "\C-c\C-w" 'gnus-uu-interactive-save-all-files)
- (define-key gnus-uu-mode-map "\C-c\C-o" 'gnus-uu-interactive-save-original-file)
- )
-
- (defun gnus-uu-interactive-save-original-file ()
- (interactive)
- (let (file)
- (if (file-exists-p
- (setq file (concat gnus-uu-tmp-dir
- (or gnus-uu-file-name gnus-uu-shar-file-name))))
- (gnus-uu-save-file file)
- (message "Already saved."))))
-
-
- (defun gnus-uu-interactive-save-current-file-silent ()
- "hei"
- (interactive)
- (gnus-uu-interactive-save-current-file t))
-
- (defun gnus-uu-interactive-save-current-file (&optional dont-ask silent)
- "Saves the file referred to on the current line."
- (interactive)
- (let (files beg line file)
- (setq files (copy-sequence gnus-uu-interactive-file-list))
- (beginning-of-line)
- (setq beg (point))
- (end-of-line)
- (setq line (buffer-substring beg (point)))
- (while (and files
- (not (string-match
- (concat "" (regexp-quote (setq file (car files))) "")
- line)))
- (setq files (cdr files)))
- (beginning-of-line)
- (forward-line 1)
- (if (not files)
- (if (not silent)
- (progn (message "Could not find file") (sit-for 2)))
- (gnus-uu-save-file file (if dont-ask gnus-uu-current-save-dir nil) silent)
- (delete-region beg (point)))))
-
-
- (defun gnus-uu-interactive-save-all-files ()
- "Saves all files referred to on the current line."
- (interactive)
- (let (dir)
- (goto-char 1)
- (setq dir (gnus-uu-get-current-dir "Where do you want the files? "))
- (while (not (eobp))
- (gnus-uu-interactive-save-current-file t t))))
-
-
-
-
- (defun gnus-uu-mode ()
- "Major mode for editing view commands in gnus-uu.
-
-
- Commands:
- Return, C-c C-v, C-c C-x Execute the current command
- C-c C-c End interactive mode
- C-c s Save the current file
- C-c C-s Save the current file without asking
- where to put it
- C-c C-a Save all files
- C-c C-o Save the original file: If the files
- originated in an archive, the archive
- file is saved.
- "
- (interactive)
- (kill-all-local-variables)
- (use-local-map gnus-uu-mode-map)
- (setq mode-name "gnus-uu")
- (setq major-mode 'gnus-uu-mode)
- )
-
- (define-key gnus-uu-mode-map "\C-c\C-x" 'gnus-uu-interactive-execute)
- (define-key gnus-uu-mode-map "\C-c\C-v" 'gnus-uu-interactive-execute)
- (define-key gnus-uu-mode-map "\C-m" 'gnus-uu-interactive-execute)
- (define-key gnus-uu-mode-map "\C-c\C-c" 'gnus-uu-interactive-end)
- (define-key gnus-uu-mode-map "\C-cs"
- 'gnus-uu-interactive-save-current-file)
- (define-key gnus-uu-mode-map "\C-c\C-s"
- 'gnus-uu-interactive-save-current-file-silent)
- (define-key gnus-uu-mode-map "\C-c\C-a" 'gnus-uu-interactive-save-all-files)
- (define-key gnus-uu-mode-map "\C-c\C-o" 'gnus-uu-interactive-save-original-file)
-
- (provide 'gnus-uu)
-